layui.define(['upload', 'jquery', 'layer'], function (exports) {
    var $ = layui.jquery;
    var layer = layui.layer;
    var upload = layui.upload;
    var _MOD = 'multipleUpload';
    var openClass = 'dropdown-open';
    var dropdownClass = 'multipleUpload-dropdown-menu';
    var dropNavClass = 'multipleUpload-dropdown-menu-nav';
    var hoverClass = 'multipleUpload-dropdown-hover';
    var fixedClass = 'fixed';
    var animClass = 'layui-anim layui-anim-upbit';
    var popAnimClass = 'layui-anim layui-anim-fadein';
    // 默认按钮
    var defaultBtn = [
        {
            name: '移除',
            icon: 'layui-icon-delete',
            type: 'multipleUpload_btn_default_1'
        },
        {
            name: '查看',
            icon: 'layui-icon-picture',
            type: 'multipleUpload_btn_default_2'
        }
    ];

    // 定义参数异常类
    function multipleUploadError(message) {
        this.name = 'multipleUploadError';
        this.message = message;
        this.stack = (new Error()).stack;
    }

    multipleUploadError.prototype = Object.create(Error.prototype);
    multipleUploadError.prototype.constructor = multipleUploadError;

    var multipleUpload = function (opt) {
        this.version = 'multipleUpload-1.0';
        this.tmpId = new Date().getTime() + Math.floor(Math.random() * (999999 - 111111)) + 111111;
        this.templateId = 'addTemplate_' + this.tmpId;
        this.pictureId = 'picture_' + this.tmpId;
        if ($('#ew-css-multipleUpload').length <= 0) {
            layui.link(layui.cache.base + 'multipleUpload/multipleUpload.css');
        }
        // 上传的实例
        this.insUpload = null;
        // 上传实例的图片信息
        this.uploadData = !opt.data ? [] : JSON.parse(JSON.stringify(opt.data));

        /**
         * 系统错误回调
         * @param error
         * @private
         */
        const _error = (error) => {

        }

        // 配置项
        this.options = $.extend(true, {
            className: opt.className || '',
            upload_limit: opt.upload_limit || 0,
            error: opt.error || _error,
            data: opt.data || [],
            btn: opt.btn || null,
            hasDefaultBtn: opt.hasDefaultBtn || true,
            on: opt.on || null,

        }, opt);
        this.init();  // 初始化页面数据
        this.bindEvents();
    };

    /**
     * 渲染初始化
     */
    multipleUpload.prototype.init = function () {
        // 检查必要参数是否填充了
        var that = this;
        var options = this.options;
        var mustParameter = ['elem', 'upload_url', 'upload_done'];
        for (var x = 0; x < mustParameter.length; x++) {
            if (!options.hasOwnProperty(mustParameter[x]) || !options[mustParameter[x]]) {
                throw new multipleUploadError(mustParameter[x] + ' is must assign ！');
            }
        }
        var components = this.getComponents();
        var contentHtml = '';
        var btnHtml = that.btnRender();
        if (options.hasOwnProperty('unshift') && options.unshift) {
            options.data.push({
                name: '点击上传',
                url: layui.cache.base + 'multipleUpload/images/add_template.png',
                is_add: 1
            });
        } else {
            options.data.unshift({
                name: '点击上传',
                url: layui.cache.base + 'multipleUpload/images/add_template.png',
                is_add: 1
            });
        }

        /**
         * 基础的html
         */
        var startHtml = '<div class="layui-form layui-row layui-col-space10" id="' + that.tmpId + '">';
        var endHtml = '</div>'
        if (options.data.length > 0) {
            if (options.hasOwnProperty('parseData') && options.parseData) {
                options.data = options.parseData(options.data)
            }
            for (var i = 0; i < options.data.length; i++) {
                var tempHtml = '';
                if (options.data[i].hasOwnProperty('is_add') && options.data[i]['is_add'] === 1) {
                    tempHtml = '<div class="layui-col-md2 is_add" id="' + this.templateId + '">' +
                        '<div class="project-list-item">' +
                        '<div style="height:120px;position: relative">' +
                        '<img alt="" class="project-list-item-icon" src="' + options.data[i]['url'] + '"/></div>' +
                        '<div class="project-list-item-body">' +
                        '<h2 style="text-align: center;height: 20.8px">' + options.data[i]['name'] + '</h2></div></div></div>';
                } else {
                    tempHtml = '<div class="layui-col-md2 ' + this.options.className + ' ' + this.pictureId + '">' + btnHtml +
                        '<div class="project-list-item" data-image-index="' + options.data[i]['index'] + '">' +
                        '<div class="cover_content">' +
                        '<img alt="" class="project-list-item-cover" src="' + options.data[i]['url'] + '"/></div></div></div>';
                    // '<div class="project-list-item-body">' +
                    // '<h2 style="text-align: center;height: 20.8px">' + options.data[i]['name'] + '</h2></div></div>';
                }
                contentHtml += tempHtml
            }
        }

        var totalHtml = startHtml + contentHtml + endHtml;
        components.$elem.html(totalHtml);
    };

    /**
     * 渲染按钮
     * @returns {string}
     */
    multipleUpload.prototype.btnRender = function () {
        var options = this.options;
        var btnHtml = '';
        if ((!options.btn || options.btn.length === 0) && options.hasDefaultBtn) {
            options.btn = defaultBtn;
        }
        if (options.hasOwnProperty('btn') && options.btn) {
            btnHtml = ' <div class="multipleUpload-dropdown-menu multipleUpload-dropdown-hover">' +
                '                <button type="button" class="layui-btn layui-btn-normal layui-btn-sm">操作<i class="layui-icon layui-icon-drop"></i>' +
                '                </button><ul class="multipleUpload-dropdown-menu-nav">'
            if (options.btn instanceof Array && options.btn.length > 0) {
                for (var j = 0; j < options.btn.length; j++) {
                    btnHtml += '<li class="multipleUpload_btn" data-type="' + (options.btn[j]['type'] || "") + '" data-index="' + j + '"><a><i class="layui-icon ' + (options.btn[j]['icon'] || "layui-icon-template-1") + '"></i>' + options.btn[j]['name'] + '</a></li>';
                }
            } else if (options.btn instanceof Object) {
                btnHtml += '<li class="multipleUpload_btn" data-type="" data-index="-1"><a><i class="layui-icon ' + (options.btn['icon'] || "layui-icon-template-1") + '"></i>' + options.btn['name'] + '</a></li>';
            }
            btnHtml = '<div class="edit_content" style="display: none">' + btnHtml + '</ul></div></div>';
        }
        console.log(btnHtml);
        return btnHtml;
    }

    /**
     * 动态加载图片块
     * @param url
     * @param index
     */
    multipleUpload.prototype.dynamicRender = function (url, index) {
        //var components = this.getComponents();
        var options = this.options;
        var btnHtml = this.btnRender();
        var tempHtml = '<div class="layui-col-md2 ' + this.pictureId + '">' + btnHtml +
            '<div class="project-list-item" data-image-index="' + index + '">' +
            '<div class="cover_content">' +
            '<img class="project-list-item-cover" src="' + url + '"/></div></div></div>';
        if (options.hasOwnProperty('unshift') && options.unshift) {
            $(tempHtml).insertBefore('#' + this.templateId);
        } else {
            $(tempHtml).insertAfter('#' + this.templateId);
        }
    }

    /**
     * 绑定相关事件
     */
    multipleUpload.prototype.bindEvents = function () {
        var that = this;
        var options = this.options;
        var components = this.getComponents();

        /* 事件公共返回对象 */
        var commonMember = function (ext) {
            var $item = $(ext);
            var obj = {
                elem: $item,  //当前item的dom
                index: $item.attr('data-index') // 当前item索引
            };
            return $.extend(obj, ext);
        };

        // 菜单显示
        var hoverSelector = '.' + dropdownClass + '.' + hoverClass;
        $(document).off('mouseenter.dropdown').on('mouseenter.dropdown', hoverSelector, function () {
            that.show(components.$elem.find('.' + dropNavClass));
        });

        // 菜单隐藏
        $(document).off('mouseleave.dropdown').on('mouseleave.dropdown', hoverSelector, function () {
            components.$elem.find('.' + dropNavClass).parent('.' + dropdownClass).removeClass(openClass);
        });

        // 操作按钮显示
        $(document).off('mouseenter.' + that.pictureId).on("mouseenter." + that.pictureId, "." + that.pictureId, function () {
            var elem = $(this).find('.edit_content');
            if (elem.css('display') === 'none') {
                elem.show();
            }
        });

        // 操作按钮隐藏
        $(document).off('mouseleave.' + that.pictureId).on("mouseleave." + that.pictureId, "." + that.pictureId, function () {
            $(this).find('.edit_content').hide();
        });

        // 操作按钮点击事件
        $(document).off('click.a.pictureId').on('click.multipleUpload_btn', '.multipleUpload_btn', function () {
            var btnType = $(this).attr('data-type');
            var btnIndex = $(this).attr('data-index');
            var imageIndex = $(this).parents('.' + that.pictureId).find('.project-list-item').attr('data-image-index');
            if (btnType === 'multipleUpload_btn_default_1') {
                // 执行删除操作
                $(this).parents('.' + that.pictureId).remove();
                for (var i = 0; i < that.uploadData.length; i++) {
                    if (that.uploadData[i]['index'] == imageIndex) {
                        that.uploadData.splice(i, 1);
                    }
                }

                if (that.options.upload_limit > 0
                    && that.uploadData.length < that.options.upload_limit
                ) {
                    // 隐藏
                    $('#' + that.tmpId).find('.is_add').show();
                }
            } else if (btnType === 'multipleUpload_btn_default_2') {
                // 执行查看操作
                var startIndex = 0;
                var currentUrl = $(this).parents('.' + that.pictureId).find('.project-list-item-cover').attr('src');
                var imgList = that.uploadData.map(function (d, index) {
                    if (currentUrl === d.url) {
                        startIndex = index;
                    }
                    return {
                        alt: d.name || '',
                        src: d.url
                    }
                });
                layer.photos({
                    photos: {data: imgList, start: startIndex},
                    shade: .1,
                    closeBtn: true
                });
            } else {
                // 外部设定的btn
                if ((options.btn instanceof Array)) {
                    if (options.btn[btnIndex].hasOwnProperty('on') && typeof options.btn[btnIndex].on === 'function') {
                        return options.btn[btnIndex].on($(this))
                    } else {
                        if (options.on) {
                            return options.on($(this), btnIndex)
                        } else {
                            layui.event.call(this, _MOD, 'btnClick(' + components.filter + ')', commonMember(this));
                        }
                    }
                } else if (options.btn instanceof Object) {
                    if (options.btn.hasOwnProperty('on') && typeof options.btn.on === 'function') {
                        return options.btn.on($(this))
                    } else {
                        if (options.on) {
                            return options.on($(this))
                        } else {
                            layui.event.call(this, _MOD, 'btnClick(' + components.filter + ')', commonMember(this));
                        }
                    }
                }
            }
        });

        /**
         * 绑定上传按钮 图片上传
         */
        that.insUpload = upload.render({
            elem: '#' + this.templateId,
            url: options.upload_url,
            auto: true,
            accept: 'images',
            exts: 'jpg|png|jpeg',
            multiple: true,
            choose: function (obj) {
                if (that.options.upload_limit > 0
                    && that.uploadData.length >= that.options.upload_limit
                ) {
                    that.options.error('上传数已达上限');
                    return false;
                }
                if (options.upload_choose) {
                    options.upload_choose(obj);
                }
            },
            before: function (obj) {
                layer.load(2); //上传loading
                if (options.upload_before) {
                    options.upload_before(obj);
                }
            },
            done: function (res, index) {
                layer.closeAll('loading'); //关闭loading
                // 上传图片的回调
                options.upload_done(res, index, function (url) {
                    that.dynamicRender(url, index);
                    // 塞入全局图片数组
                    that.uploadData.push({
                        index: index,
                        url: url
                    })
                });
                if (that.options.upload_limit > 0
                    && that.uploadData.length >= that.options.upload_limit
                ) {
                    // 隐藏
                    $('#' + that.tmpId).find('.is_add').hide();
                }
            },
            error: function (index, upload) {
                layer.closeAll('loading'); //关闭loading
                layer.msg('系统异常，上传图片失败！', {icon: 2});
                if (options.upload_error) {
                    options.upload_error(index, upload);
                }
                return false;
            }
        });
    };

    /** 获取容器信息 */
    multipleUpload.prototype.getComponents = function () {
        var that = this;
        var $elem = $(that.options.elem);
        var filter = $elem.attr('lay-filter');
        if (!filter) {
            filter = that.options.elem.substring(1);
            $elem.attr('lay-filter', filter);
        }
        return {
            $elem: $elem,  // 容器
            templetHtml: $(that.options.templet).html(),  // 模板内容
            filter: filter  // 容器的lay-filter
        };
    };

    // 展开下拉菜单
    multipleUpload.prototype.show = function ($dropNav) {
        if ($dropNav && $dropNav.length > 0) {
            if ($dropNav.hasClass('dropdown-popconfirm')) {
                $dropNav.removeClass(animClass);
                $dropNav.addClass(popAnimClass);
            } else {
                $dropNav.removeClass(popAnimClass);
                $dropNav.addClass(animClass);
            }
            var position;  // 获取位置
            $dropNav.addClass('dropdown-bottom-left');
            position = 'bottom-left';
            this.forCenter($dropNav, position);
            $dropNav.parent('.' + dropdownClass).addClass(openClass);
            return position;
        }
        return false;
    }

    // 解决绝对定位因动画导致平移失效
    multipleUpload.prototype.forCenter = function ($dropNav, position) {
        if (!$dropNav.hasClass(fixedClass)) {
            var wTrigger = $dropNav.parent().outerWidth(), hTrigger = $dropNav.parent().outerHeight();
            var wDrop = $dropNav.outerWidth(), hDrop = $dropNav.outerHeight();
            var pParts = position.split('-'), dropSide = pParts[0], dropPosition = pParts[1];  // 显示方向
            if ((dropSide === 'top' || dropSide === 'bottom') && dropPosition === 'center') {
                $dropNav.css('left', (wTrigger - wDrop) / 2);
            }
            if ((dropSide === 'left' || dropSide === 'right') && dropPosition === 'center') {
                $dropNav.css('top', (hTrigger - hDrop) / 2);
            }
        }
    }

    /**
     * 获取本实例上传的图片列表
     * @returns {[]|Array}
     */
    multipleUpload.prototype.getUploadImages = function () {
        return this.uploadData;
    };

    /**
     * 获取上传实例
     * @returns {*}
     */
    multipleUpload.prototype.getUploadInstance = function () {
        return this.insUpload;
    };

    /** 外部方法 */
    var iS = {
        /* 渲染 */
        render: function (options) {
            return new multipleUpload(options);
        }
    };
    exports(_MOD, iS);
});